﻿using StudentLive.Common;
using StudentLive.DataModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Search;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Notifications;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.ApplicationSettings;
using Windows.UI;
using Callisto.Controls;
using StudentLive.InnerPages;


// The Grid App template is documented at http://go.microsoft.com/fwlink/?LinkId=234226

namespace StudentLive
{
    /// <summary>
    /// Provides application-specific behavior to supplement the default Application class.
    /// </summary>
    sealed partial class App : Application
    {
        private Color _background = Windows.UI.Colors.Black;

        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
            this.UnhandledException += App_UnhandledException;

        }

        async void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            e.Handled = true;

            MessageDialog dialog = new MessageDialog(e.Exception.Message, "Sorry!");
            await dialog.ShowAsync();
        }

        protected override async void OnLaunched(LaunchActivatedEventArgs args)
        {
            GenerateTiles();
            bool loadState = (args.PreviousExecutionState == ApplicationExecutionState.Terminated);
            //ExtendedSplash extendedSplash = new ExtendedSplash(args.SplashScreen, loadState);
            if (loadState)
            {
                await StudentLive.Common.SuspensionManager.RestoreAsync();
            }
            // Check if database installed? 
            // if yes go on, if not copy the database 

            Frame rootFrame = Window.Current.Content as Frame;

            if (rootFrame == null)
            {
                rootFrame = new Frame();

                var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;

                string langId = (string)localSettings.Values[Constants.LanguageId];
                langId = langId == null ? "en" : langId;
                localSettings.Values[Constants.LanguageId] = langId;

                Object isLoggedIn = localSettings.Values[Constants.IsLoggedIn];

                if (args.PreviousExecutionState != ApplicationExecutionState.Running)
                {
                    if (isLoggedIn == null || !(bool)isLoggedIn)
                    {
                        LoginPage login = new LoginPage(args.SplashScreen, loadState);
                        rootFrame.Content = login;
                    }
                    else
                    {
                        ExtendedSplash extendedSplash = new ExtendedSplash(args.SplashScreen, loadState);
                        rootFrame.Content = extendedSplash;
                    }
                }

                Window.Current.Content = rootFrame;

                StudentLive.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame");
            }

            SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;

            Window.Current.Activate();
        }

        void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
        {
            // Add an About command
            var preferences = new SettingsCommand("preferences", "Preferences", (handler) =>
            {
                var settings = new SettingsFlyout();
                settings.Content = new PreferencesUserControl();
                settings.HeaderBrush = new SolidColorBrush(_background);
                settings.Background = new SolidColorBrush(_background);
                settings.HeaderText = "Preferences";
                settings.IsOpen = true;
            });


            args.Request.ApplicationCommands.Add(preferences);

            var about = new SettingsCommand("about", "About", (handler) =>
                {
                    var settings = new SettingsFlyout();
                    settings.Content = new AboutUserControl();
                    settings.HeaderBrush = new SolidColorBrush(_background);
                    settings.Background = new SolidColorBrush(_background);
                    settings.HeaderText = "About";
                    settings.IsOpen = true;
                });

            args.Request.ApplicationCommands.Add(about);


        }


        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            await SuspensionManager.SaveAsync();  // THIS CAUSED ERROR WHEN REMOTE MACHINE ( Slate ) TESTING
            deferral.Complete();
        }


        private void GenerateTiles()
        {
            TileUpdateManager.CreateTileUpdaterForApplication().Clear();

            var uris = new List<Uri>();
            const string baseUri = "http://localhost:2345/api/tileupdater/get?position=";

            for (var i = 0; i < 5; i++)
            {
                uris.Add(new Uri(baseUri + i, UriKind.Absolute));
            }

            TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true);
            TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdateBatch(uris, PeriodicUpdateRecurrence.HalfHour);

        }

        protected async override void OnSearchActivated(Windows.ApplicationModel.Activation.SearchActivatedEventArgs args)
        {
            // TODO: Register the Windows.ApplicationModel.Search.SearchPane.GetForCurrentView().QuerySubmitted
            // event in OnWindowCreated to speed up searches once the application is already running

            // If the Window isn't already using Frame navigation, insert our own Frame
            var previousContent = Window.Current.Content;
            var frame = previousContent as Frame;

            // If the app does not contain a top-level frame, it is possible that this 
            // is the initial launch of the app. Typically this method and OnLaunched 
            // in App.xaml.cs can call a common method.
            if (frame == null)
            {
                // Create a Frame to act as the navigation context and associate it with
                // a SuspensionManager key
                frame = new Frame();
                StudentLive.Common.SuspensionManager.RegisterFrame(frame, "AppFrame");

                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    // Restore the saved session state only when appropriate
                    try
                    {
                        await StudentLive.Common.SuspensionManager.RestoreAsync();
                    }
                    catch (StudentLive.Common.SuspensionManagerException)
                    {
                        //Something went wrong restoring state.
                        //Assume there is no state and continue
                    }
                }
            }

            frame.Navigate(typeof(SearchResultsPage), args.QueryText);
            Window.Current.Content = frame;

            // Ensure the current window is active
            Window.Current.Activate();
        }

        #region private helpers

        private async void InstallDatabase()
        {
            StorageFile seedFile = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
            "Database\\StudentLive.sqlite"));

            await seedFile.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder);
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            localSettings.Values[Constants.IsDatabaseInstalled] = true;


            // To be removed install sample data..
            StorageFile doc = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
            "Database\\Document1.docx"));
            await doc.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder);

            doc = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
            "Database\\Document2.docx"));
            await doc.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder);

            doc = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
            "Database\\Document3.docx"));
            await doc.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder);

            doc = await StorageFile.GetFileFromPathAsync(Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path,
            "Database\\Document4.docx"));
            await doc.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder);

        }

        #endregion

    }
}
